package com.portal.framework.util;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

/**
 * 使用jaxb2,把一个对象生成xml文件,和把一个xml转换成对象 <BR>
 * 用到的元数据:
 * <li>@ XmlAttribute
 * <li>@ XmlElement
 * <li>@ XmlRootElement <BR>
 *      注意:
 *      <li> 如果 XmlAttribute和XmlAttribute元数据写在属性上,不能添加getter方法,或则会报错.可以写在构造函数中
 *      <li> 如果不在属性上写元数据,可以写在getter方法. usage:<BR>
 *      <BR>
 * <code>
 * @ XmlRootElement//表示person是一个根元素  
 * class Person {      
 *   @ XmlElement  
 *   Date birthDay; //birthday将作为person的子元素  
 *   @ XmlAttribute  
 *   String name; //name将作为person的的一个属性  
 *   @ XmlElement  
 *   Gender gender; //gender将作为person的子元素  
 *   @ XmlElement  
 *   String job; //job将作为person的子元素  
 * </code>
 * @author 卢烁波
 * @date 2007-3-10
 */
public abstract class JAXB2Util {

	/**
	 * 使用jaxb2生成xml文件
	 * 
	 * @param obj 要生成xml的对象
	 * @param genFile 生成的文件
	 * @throws Exception
	 */
	public static void toXML(Object obj, File genFile) {
		if (genFile != null && genFile.getParentFile() != null) {
			genFile.getParentFile().mkdirs();
		}

		try {
			JAXBContext context = JAXBContext.newInstance(obj.getClass());
			Marshaller m = context.createMarshaller();
			FileWriter fw = new FileWriter(genFile);
			m.marshal(obj, fw);
		} catch (JAXBException jaxbe) {
			jaxbe.printStackTrace();
			throw new RuntimeException(jaxbe);
		} catch (IOException e) {
			e.printStackTrace();
			throw new RuntimeException(e);
		}
	}

	/**
	 * 根据XML文件,生成对象
	 * 
	 * @param <T> 该对象的类型
	 * @param retClass 返回的class
	 * @param file xml文件
	 * @return
	 */
	public static <T> T fromXML(Class<T> retClass, File file) {
		try {
			JAXBContext context = JAXBContext.newInstance(retClass);
			FileReader fr = new FileReader(file);
			Unmarshaller um = context.createUnmarshaller();
			T ret = retClass.cast(um.unmarshal(fr));
			return ret;
		} catch (JAXBException jaxbe) {
			jaxbe.printStackTrace();
			return null;
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}
}
